In [1]:
import plotly.graph_objects as go
import pandas as pd
In [2]:
df = pd.read_csv("ETH-BTC - ETH-BTC.csv")
In [3]:
#First off, I am calculating the simple moving average (SMA) to get an idea of the trends followed in the time series data
In [4]:
df['20SMA'] = df.rolling(window=20, center=True, min_periods=10).mean().Close
df['50SMA'] = df.rolling(window=50, center=True, min_periods=25).mean().Close
In [5]:
candlestick = go.Candlestick(x=df['Date'], open=df['Open'], high=df['High'], low=df['Low'], close=df['Close'])
fig = go.Figure(data=[candlestick])
sma_trace1 = go.Scatter(x=df['Date'], y=df['20SMA'], mode='lines', name='20SMA')
sma_trace2 = go.Scatter(x=df['Date'], y=df['50SMA'], mode='lines', name='50SMA')
fig.add_trace(sma_trace1)
fig.add_trace(sma_trace2)
fig.update_xaxes(rangeslider_visible=False)
fig.show()
In [6]:
'''
Although SMA gives a trend of the stock prices, it is not enough to indicate when to buy/sell in the market.

During Jul-22 and Sep-Nov22 there has been prominent difference between 20SMA and 50 SMA, indicative of short term dip or spike
in prices.'''


'''
Exponential moving avergae is a better indicator as it gives more weight to recent data, hence we get an idea of how market
#was impacted due to prevalent market developments

I have found below 12-period EMA and 26-period EMA below.
'''
Out[6]:
'\nExponential moving avergae is a better indicator as it gives more weight to recent data, hence we get an idea of how market\n#was impacted due to prevalent market developments\n\nI have found below 12-period EMA and 26-period EMA below.\n'
In [7]:
df['12EMA'] = df['Close'].ewm(span=12, adjust=False).mean()
df['26EMA'] = df['Close'].ewm(span=26, adjust=False).mean()
df.head()
Out[7]:
Date Open High Low Close Adj Close Volume 20SMA 50SMA 12EMA 26EMA
0 2022-01-01 0.079536 0.079056 0.079520 0.079051 0.079051 205008 0.078424 0.075402 0.079051 0.079051
1 2022-01-02 0.079043 0.080145 0.079351 0.080886 0.080886 208711 0.078183 0.075077 0.079333 0.079187
2 2022-01-03 0.080885 0.081274 0.080666 0.080963 0.080963 260036 0.078062 0.074713 0.079584 0.079318
3 2022-01-04 0.080962 0.081830 0.080832 0.082664 0.082664 305701 0.077924 0.074452 0.080058 0.079566
4 2022-01-05 0.082668 0.081933 0.080739 0.081489 0.081489 414546 0.077844 0.074233 0.080278 0.079709
In [8]:
fig2 = go.Figure(data=[candlestick])
ema_trace1 = go.Scatter(x=df['Date'], y=df['12EMA'], mode='lines', name='12EMA')
ema_trace2 = go.Scatter(x=df['Date'], y=df['26EMA'], mode='lines', name='26EMA')
fig2.add_trace(ema_trace1)
fig2.add_trace(ema_trace2)
fig2.update_xaxes(rangeslider_visible=False)
fig2.show()
In [9]:
'''
When 12 EMA is starting to go below 26EMA (per MACD criteria), we can deduce that market is falling and hence it is better to
sell.

If we look at May-Jul 2022, it appears the market has took a fall and it is better to not buy stocks/crypto at this time. 
But seeing the brief uptrend towards end of June-22 we might get deceived into buying. But the MACD criteria clearly indicates
that that the market doesn't have an upwards momentum yet, which it later does.
'''
Out[9]:
"\nWhen 12 EMA is starting to go below 26EMA (per MACD criteria), we can deduce that market is falling and hence it is better to\nsell.\n\nIf we look at May-Jul 2022, it appears the market has took a fall and it is better to not buy stocks/crypto at this time. \nBut seeing the brief uptrend towards end of June-22 we might get deceived into buying. But the MACD criteria clearly indicates\nthat that the market doesn't have an upwards momentum yet, which it later does.\n"
In [10]:
import math
dfc=df.copy()
dfc['Yest_Close'] = dfc['Close'].shift(1).dropna()
def diff(a, b):
    return abs(a-b)

dfc['H-L'] = dfc.apply(lambda x: diff(x['High'], x['Low']), axis=1)
dfc['H-C'] = dfc.apply(lambda x: diff(x['High'], x['Yest_Close']), axis=1)
dfc['L-C'] = dfc.apply(lambda x: diff(x['Low'], x['Yest_Close']), axis=1)

dfc['TR'] = dfc.apply(lambda x: max(x['H-L'], x['H-C'], x['L-C']), axis=1)
In [11]:
def atr(prev_atr, cur_tr, n):
    return 1.0*((prev_atr*(n-1))+cur_tr)/n

dfc['7ATR'] = dfc.rolling(window=7, center=True).mean().TR.shift(1)
dfc['21ATR'] = dfc.rolling(window=21, center=True).mean().TR.shift(1)

dfc['7ATR'] = dfc.apply(lambda x: atr(x['7ATR'], x['TR'], 7), axis=1)
dfc['21ATR'] = dfc.apply(lambda x: atr(x['21ATR'], x['TR'], 21), axis=1)
In [12]:
atr_trace1 = go.Scatter(x=dfc['Date'], y=dfc['7ATR'], mode='lines', name='7ATR')
atr_trace2 = go.Scatter(x=dfc['Date'], y=dfc['21ATR'], mode='lines', name='21ATR')
fig3 = go.Figure()
fig3.add_trace(atr_trace1)
fig3.add_trace(atr_trace2)
fig3.update_layout(
    autosize=False,
    width=1000,
    height=300
)
fig3.show()
In [13]:
'''
The ATR data above indicates te periods when market undergoes volatility. When there is a steep change in short ATR, it is 
better to stay away from the markets to avoid risk (only if the change is matched by a similar trend in MACD though)
'''
Out[13]:
'\nThe ATR data above indicates te periods when market undergoes volatility. When there is a steep change in short ATR, it is \nbetter to stay away from the markets to avoid risk (only if the change is matched by a similar trend in MACD though)\n'
In [14]:
def gain(tod, yest):
    if tod>yest:
        return tod-yest
    else:
        return 0

def loss(tod, yest):
    if tod>yest:
        return 0
    else:
        return yest-tod

dfc['Gain'] = dfc.apply(lambda x: gain(x['Close'], x['Yest_Close']), axis=1)
dfc['Loss'] = dfc.apply(lambda x: loss(x['Close'], x['Yest_Close']), axis=1)
dfc['Avg_Gain'] = dfc.rolling(window=14, center=True, min_periods=11).mean().Gain.shift(1)
dfc['Avg_Loss'] = dfc.rolling(window=14, center=True, min_periods=11).mean().Loss.shift(1)

def avg_gainorloss(prev_avg, cur, n=14):
    return 1.0*((prev_avg*(n-1))+cur)/n

dfc['Avg_Gain'] = dfc.apply(lambda x: avg_gainorloss(x['Avg_Gain'], x['Gain'], 14), axis=1)
dfc['Avg_Loss'] = dfc.apply(lambda x: avg_gainorloss(x['Avg_Loss'], x['Loss'], 14), axis=1)
In [15]:
def rsi(gain, loss):
    return 100.0*gain/(gain+loss)
dfc['RSI'] = dfc.apply(lambda x: rsi(x['Avg_Gain'], x['Avg_Loss']), axis=1)
In [16]:
rsi_trace = go.Scatter(x=dfc['Date'], y=dfc['RSI'], mode='lines', name='RSI')
fig4 = go.Figure()
fig4.add_trace(rsi_trace)
fig4.add_hline(y=70, line_width=1, line_dash="dash", line_color="red")
fig4.add_hline(y=30, line_width=1, line_dash="dash", line_color="red")
fig4.update_layout(
    autosize=False,
    width=1000,
    height=300
)


fig4.show()
In [17]:
'''
From RSI, bearish and bullish situations signalling bad and good occasions to invest'''
Out[17]:
'\nFrom RSI, bearish and bullish situations signalling bad and good occasions to invest'
In [18]:
final = pd.read_csv("ETH-BTC - ETH-BTC.csv")
def FCI(short, long, gain, loss):
    return 100-(100/(1+(gain*short/(loss*long))))
final['FCI'] = dfc.apply(lambda x: FCI(x['7ATR'], x['21ATR'], x['Avg_Gain'], x['Avg_Loss']), axis=1)

def returns(cur, prev):
    return 100.0*(cur-prev)/prev

final['Return'] = dfc.apply(lambda x: returns(x['Close'], x['Yest_Close']), axis=1)

def dd(low, high):
    return 100.0*(low-high)/high

final['Max_DD'] = dfc.apply(lambda x: dd(x['Low'], x['High']), axis=1)
In [19]:
candlestick = go.Candlestick(x=final['Date'], open=final['Open'], high=final['High'], low=final['Low'], close=final['Close'])
fig7 = go.Figure(data=[candlestick])
fig5 = go.Figure()
fig6 = go.Figure()
trace1 = go.Scatter(x=final['Date'], y=final['FCI'], mode='lines', name='FCI')
trace2 = go.Scatter(x=final['Date'], y=final['Return'], mode='lines', name='Return')
trace3 = go.Scatter(x=final['Date'], y=final['Max_DD'], mode='lines', name='Max_DD')
fig5.add_trace(trace2)
fig5.add_trace(trace3)
fig7.update_xaxes(rangeslider_visible=False)
fig6.add_trace(trace1)
fig7.show()
fig5.show()
fig6.show()
In [20]:
'''
From these graphs of the market indicators, we can see that right after Jul and Nov-22 were great occasions to invest.

The general strategy is try to stay away from RSI out-of-line situations, be mindful of moving average and MACD (as per above
seen criteria, to correlate these to current market trends to foresee good occasions to buy. When ATR is spiking and market is
in uptrend (MACD is signalling upwards momentum), that is a best time to invest to get maxium returns (as seen right above).

We can also look at all the above market indicators to not be deceived by a good indication from one of the indicators 
during brief momentum changes, orvice versa (false alarms)'''
Out[20]:
'\nFrom these graphs of the market indicators, we can see that right after Jul and Nov-22 were great occasions to invest.\n\nThe general strategy is try to stay away from RSI out-of-line situations, be mindful of moving average and MACD (as per above\nseen criteria, to correlate these to current market trends to foresee good occasions to buy. When ATR is spiking and market is\nin uptrend (MACD is signalling upwards momentum), that is a best time to invest to get maxium returns (as seen right above).\n\nWe can also look at all the above market indicators to not be deceived by a good indication from one of the indicators \nduring brief momentum changes, orvice versa (false alarms)'
In [21]:
final.iloc[20:50, :]
Out[21]:
Date Open High Low Close Adj Close Volume FCI Return Max_DD
20 2022-01-21 0.073818 0.073776 0.069113 0.070162 0.070162 735004 20.086751 -4.894745 -6.320484
21 2022-01-22 0.070251 0.071354 0.067840 0.068660 0.068660 781316 22.122062 -2.140760 -4.924741
22 2022-01-23 0.068710 0.070447 0.068450 0.069880 0.069880 454326 36.230295 1.776872 -2.834755
23 2022-01-24 0.069904 0.069940 0.065365 0.066577 0.066577 769917 31.901461 -4.726674 -6.541321
24 2022-01-25 0.066579 0.066872 0.065940 0.066459 0.066459 437836 34.855350 -0.177238 -1.393707
25 2022-01-26 0.066450 0.069838 0.066425 0.066971 0.066971 576084 44.251163 0.770400 -4.887024
26 2022-01-27 0.066948 0.067957 0.065129 0.065243 0.065243 434230 44.687498 -2.580221 -4.161455
27 2022-01-28 0.065206 0.067452 0.065366 0.067411 0.067411 388156 54.786059 3.322962 -3.092570
28 2022-01-29 0.067398 0.068231 0.067367 0.068097 0.068097 292936 46.769575 1.017638 -1.266287
29 2022-01-30 0.068136 0.069011 0.068111 0.068661 0.068661 250575 57.800044 0.828230 -1.304140
30 2022-01-31 0.068656 0.069817 0.067486 0.069856 0.069856 358033 63.798226 1.740435 -3.338728
31 2022-02-01 0.069846 0.071643 0.069837 0.072067 0.072067 340571 58.776585 3.165082 -2.520832
32 2022-02-02 0.072063 0.072434 0.071387 0.072602 0.072602 375512 64.219799 0.742365 -1.445454
33 2022-02-03 0.072585 0.073328 0.071077 0.072109 0.072109 343309 59.369525 -0.679045 -3.069769
34 2022-02-04 0.072160 0.071892 0.072127 0.071892 0.071892 457514 62.036823 -0.300933 0.326879
35 2022-02-05 0.071913 0.073030 0.071922 0.072745 0.072745 316161 61.130224 1.186502 -1.517185
36 2022-02-06 0.072753 0.072139 0.071766 0.072089 0.072089 223190 40.077198 -0.901780 -0.517057
37 2022-02-07 0.072088 0.071729 0.071861 0.071680 0.071680 346646 42.474511 -0.567354 0.184026
38 2022-02-08 0.071692 0.071137 0.070734 0.070778 0.070778 388411 40.519477 -1.258371 -0.566513
39 2022-02-09 0.070746 0.073051 0.070825 0.073061 0.073061 314652 57.137580 3.225579 -3.047186
40 2022-02-10 0.073076 0.072577 0.070563 0.070641 0.070641 427624 42.369742 -3.312301 -2.774984
41 2022-02-11 0.070639 0.071522 0.068508 0.069029 0.069029 378323 43.270733 -2.281961 -4.214088
42 2022-02-12 0.069029 0.069745 0.068391 0.069059 0.069059 266410 49.801268 0.043460 -1.941358
43 2022-02-13 0.069045 0.069170 0.067773 0.068333 0.068333 214585 46.751693 -1.051275 -2.019662
44 2022-02-14 0.068255 0.069296 0.068128 0.068882 0.068882 285641 43.299428 0.803419 -1.685523
45 2022-02-15 0.068888 0.071317 0.068659 0.071337 0.071337 312309 49.068614 3.564066 -3.727022
46 2022-02-16 0.071350 0.071376 0.070274 0.071149 0.071149 280980 38.437428 -0.263538 -1.543936
47 2022-02-17 0.071127 0.071488 0.071083 0.071081 0.071081 391243 40.155437 -0.095574 -0.566529
48 2022-02-18 0.071152 0.071818 0.069267 0.069589 0.069589 393400 30.701708 -2.099014 -3.552034
49 2022-02-19 0.069568 0.070265 0.068153 0.068882 0.068882 243611 33.623568 -1.015965 -3.005764
In [ ]: